import React, { useState, useEffect } from 'react';
import * as tf from '@tensorflow/tfjs';
import { preprocessData } from '../../utils/dataPreprocessor';
import { applyMontyHall } from '../../utils/montyHallLogic';
import './MontyHall.css';

function MontyHall({ model, data }) {
  const [sequence, setSequence] = useState([]);
  const [predictions, setPredictions] = useState([]);
  const [excludedNumbers, setExcludedNumbers] = useState([]);
  const [adjustedPredictions, setAdjustedPredictions] = useState([]);
  const [numToExclude, setNumToExclude] = useState(3);
  const [isProcessing, setIsProcessing] = useState(false);
  const [history, setHistory] = useState([]);

  useEffect(() => {
    if (data && data.length > 0) {
      const initialSequence = data.slice(-10);
      setSequence(initialSequence);
    }
  }, [data]);

  const handlePredict = async () => {
    if (!model || !sequence.length) return;
    
    setIsProcessing(true);
    
    try {
      // Prepare input sequence
      const inputSequence = sequence.slice(-model.input.shape[1]);
      const inputTensor = tf.tensor2d([inputSequence], [1, inputSequence.length]);
      
      // Make prediction
      const prediction = model.predict(inputTensor);
      const predictionData = await prediction.data();
      
      // Format predictions with probabilities
      const formattedPredictions = Array.from(predictionData)
        .map((prob, num) => ({
          number: num,
          probability: prob,
          percentage: (prob * 100).toFixed(2) + '%'
        }))
        .sort((a, b) => b.probability - a.probability);
      
      setPredictions(formattedPredictions);
      
      // Randomly exclude n numbers (Monty Hall)
      const excluded = [];
      const candidates = [...formattedPredictions]
        .sort(() => Math.random() - 0.5) // Shuffle
        .slice(0, numToExclude)
        .map(item => item.number);
      
      setExcludedNumbers(candidates);
      
      // Apply Monty Hall adjustment
      const adjusted = applyMontyHall(formattedPredictions, candidates);
      setAdjustedPredictions(adjusted);
      
      // Update history
      const nextNumber = sequence[sequence.length - 1];
      const originalCorrect = formattedPredictions.slice(0, 6).some(p => p.number === nextNumber);
      const adjustedCorrect = adjusted.slice(0, 6).some(p => p.number === nextNumber);
      
      setHistory(prev => [
        ...prev,
        {
          sequence: [...sequence],
          originalTop6: formattedPredictions.slice(0, 6).map(p => p.number),
          adjustedTop6: adjusted.slice(0, 6).map(p => p.number),
          actual: nextNumber,
          originalCorrect,
          adjustedCorrect,
          excludedNumbers: [...candidates]
        }
      ]);
    } catch (error) {
      console.error('Prediction error:', error);
    } finally {
      setIsProcessing(false);
    }
  };

  const addToSequence = (num) => {
    setSequence(prev => [...prev, num].slice(-20)); // Keep last 20 numbers
  };

  const clearSequence = () => {
    setSequence([]);
    setPredictions([]);
    setAdjustedPredictions([]);
    setExcludedNumbers([]);
  };

  const getAccuracyStats = () => {
    if (history.length === 0) return null;
    
    const originalCorrect = history.filter(item => item.originalCorrect).length;
    const adjustedCorrect = history.filter(item => item.adjustedCorrect).length;
    const total = history.length;
    
    return {
      originalAccuracy: (originalCorrect / total * 100).toFixed(1) + '%',
      adjustedAccuracy: (adjustedCorrect / total * 100).toFixed(1) + '%',
      improvement: ((adjustedCorrect - originalCorrect) / total * 100).toFixed(1) + '%'
    };
  };

  const accuracyStats = getAccuracyStats();

  return (
    <div className="card">
      <h2>Monty Hall Predictor</h2>
      <p className="description">
        After the model makes predictions, you can exclude {numToExclude} numbers (like in the Monty Hall problem) 
        to see how the probabilities adjust and affect prediction accuracy.
      </p>
      
      <div className="monty-controls">
        <div className="form-group">
          <label>Numbers to Exclude</label>
          <input 
            type="number" 
            min="1" 
            max="8" 
            value={numToExclude} 
            onChange={(e) => setNumToExclude(Math.min(8, Math.max(1, parseInt(e.target.value) || 3)))}
            disabled={isProcessing}
          />
        </div>
      </div>
      
      <div className="sequence-container">
        <h3>Current Sequence</h3>
        <div className="sequence-display">
          {sequence.length > 0 ? sequence.join(', ') : 'No sequence yet'}
        </div>
        
        <div className="number-pad">
          {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(num => (
            <button 
              key={num} 
              className="number-button" 
              onClick={() => addToSequence(num)}
              disabled={isProcessing}
            >
              {num}
            </button>
          ))}
        </div>
        
        <div className="sequence-controls">
          <button 
            className="button" 
            onClick={handlePredict}
            disabled={!sequence.length || isProcessing}
          >
            {isProcessing ? 'Processing...' : 'Predict with Monty Hall'}
          </button>
          
          <button 
            className="button button-clear" 
            onClick={clearSequence}
          >
            Clear Sequence
          </button>
        </div>
      </div>
      
      {excludedNumbers.length > 0 && (
        <div className="excluded-numbers">
          <h3>Excluded Numbers: {excludedNumbers.join(', ')}</h3>
        </div>
      )}
      
      {predictions.length > 0 && (
        <div className="predictions-comparison">
          <div className="original-predictions">
            <h3>Original Predictions</h3>
            <div className="top-predictions">
              {predictions.slice(0, 6).map((pred, index) => (
                <div 
                  key={pred.number} 
                  className={`prediction-item ${excludedNumbers.includes(pred.number) ? 'excluded' : ''}`}
                >
                  <span className="prediction-rank">{index + 1}.</span>
                  <span className="prediction-number">{pred.number}</span>
                  <span className="prediction-prob">{pred.percentage}</span>
                </div>
              ))}
            </div>
          </div>
          
          <div className="adjusted-predictions">
            <h3>Adjusted Predictions</h3>
            <div className="top-predictions">
              {adjustedPredictions.slice(0, 6).map((pred, index) => (
                <div key={pred.number} className="prediction-item">
                  <span className="prediction-rank">{index + 1}.</span>
                  <span className="prediction-number">{pred.number}</span>
                  <span className="prediction-prob">{pred.percentage}</span>
                </div>
              ))}
            </div>
          </div>
        </div>
      )}
      
      {accuracyStats && (
        <div className="accuracy-stats">
          <h3>Accuracy Statistics</h3>
          <div className="stats-grid">
            <div className="stat-item">
              <div className="stat-label">Original Accuracy</div>
              <div className="stat-value">{accuracyStats.originalAccuracy}</div>
            </div>
            <div className="stat-item">
              <div className="stat-label">Adjusted Accuracy</div>
              <div className="stat-value">{accuracyStats.adjustedAccuracy}</div>
            </div>
            <div className="stat-item">
              <div className="stat-label">Improvement</div>
              <div className="stat-value">{accuracyStats.improvement}</div>
            </div>
          </div>
        </div>
      )}
      
      {history.length > 0 && (
        <div className="prediction-history">
          <h3>Prediction History</h3>
          <div className="table-container">
            <table>
              <thead>
                <tr>
                  <th>Sequence</th>
                  <th>Original Top 6</th>
                  <th>Adjusted Top 6</th>
                  <th>Actual</th>
                  <th>Excluded</th>
                  <th>Original</th>
                  <th>Adjusted</th>
                </tr>
              </thead>
              <tbody>
                {history.map((item, index) => (
                  <tr key={index}>
                    <td>{item.sequence.slice(-5).join(', ')}...</td>
                    <td>{item.originalTop6.join(', ')}</td>
                    <td>{item.adjustedTop6.join(', ')}</td>
                    <td>{item.actual}</td>
                    <td>{item.excludedNumbers.join(', ')}</td>
                    <td className={item.originalCorrect ? 'correct' : 'incorrect'}>
                      {item.originalCorrect ? '✓' : '✗'}
                    </td>
                    <td className={item.adjustedCorrect ? 'correct' : 'incorrect'}>
                      {item.adjustedCorrect ? '✓' : '✗'}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      )}
    </div>
  );
}

export default MontyHall;